#include "fxcc/imgui/Editor.h"
#include "fxcc/core/graph/common/GlslShader.h"

using namespace fxcc::graph::common;
using namespace fxcc::imgui;
using namespace glslang;

template <>
bool Editor::Edit<GlslShader::UniformBlock>(const std::string& label, GlslShader::UniformBlock& inst)
{
    bool flag{ 0 };

    return flag;
}

template <>
bool Editor::Edit<glslang::TSampler>(const std::string& label, glslang::TSampler& inst)
{
    bool flag{ 0 };

    static std::map<glslang::TSamplerDim, std::string> ls =
    {
        {glslang::TSamplerDim::EsdNone,"EsdNone"},
        {glslang::TSamplerDim::Esd1D,"Esd1D"},
        {glslang::TSamplerDim::Esd2D,"Esd2D"},
        {glslang::TSamplerDim::Esd3D,"Esd3D"},
        {glslang::TSamplerDim::EsdCube,"EsdCube"},
        {glslang::TSamplerDim::EsdRect,"EsdRect"},
        {glslang::TSamplerDim::EsdBuffer,"EsdBuffer"},
        {glslang::TSamplerDim::EsdSubpass,"EsdSubpass"},
        {glslang::TSamplerDim::EsdAttachmentEXT,"EsdAttachmentEXT"},
        {glslang::TSamplerDim::EsdNumDims,"EsdNumDims"}
    };
    auto dim = inst.dim;
    ComboEnumMap<glslang::TSamplerDim>("dim", dim, ls);
    inst.dim = dim;
    bool isArray = inst.isArrayed();
    ImGui::Checkbox("IsArray", &isArray);

    return flag;
}

template <>
bool Editor::Edit<GlslShader::Type>(const std::string& label, GlslShader::Type& inst)
{
    bool flag{ 0 };
    static std::map<decltype(inst.m_BasicType), std::string> ls =
    {
    {EbtVoid,"EbtVoid"},
    {EbtFloat,"EbtFloat"},
    {EbtDouble,"EbtDouble"},
    {EbtFloat16,"EbtFloat16"},
    {EbtBFloat16,"EbtBFloat16"},
    {EbtInt8,"EbtInt8"},
    {EbtUint8,"EbtUint8"},
    {EbtInt16,"EbtInt16"},
    {EbtUint16,"EbtUint16"},
    {EbtInt,"EbtInt"},
    {EbtUint,"EbtUint"},
    {EbtInt64,"EbtInt64"},
    {EbtUint64,"EbtUint64"},
    {EbtBool,"EbtBool"},
    {EbtAtomicUint,"EbtAtomicUint"},
    {EbtSampler,"EbtSampler"},
    {EbtStruct,"EbtStruct"},
    {EbtBlock,"EbtBlock"},
    {EbtAccStruct,"EbtAccStruct"},
    {EbtReference,"EbtReference"},
    {EbtRayQuery,"EbtRayQuery"},
    {EbtHitObjectNV,"EbtHitObjectNV"},
    {EbtCoopmat,"EbtCoopmat"},
    {EbtFunction,"EbtFunction"},
    {EbtTensorLayoutNV,"EbtTensorLayoutNV"},
    {EbtTensorViewNV,"EbtTensorViewNV"},
    {EbtCoopvecNV,"EbtCoopvecNV"},
    {EbtSpirvType,"EbtSpirvType"},
    {EbtString,"EbtString"},
    {EbtNumTypes,"EbtNumTypes"}
    };

    ImGui::Text("type");
    ComboEnumMap<decltype(inst.m_BasicType)>("m_BasicType", inst.m_BasicType, ls);
    EditInst<int>("m_VectorSize", inst.m_VectorSize);
    EditInst<glslang::TSampler>("m_Sampler", inst.m_Sampler);
    return flag;
}

template <>
bool Editor::Edit<GlslShader::UniformVariable>(const std::string& label, GlslShader::UniformVariable& inst)
{
    ImGui::Text("%s", label.c_str());

    bool flag{ 0 };
    flag |= EditInst<std::string>("m_Name", inst.m_Name);
    flag |= EditInst<int>("m_Binding", inst.m_Binding);
    flag |= EditInst<int>("m_LayoutLocation", inst.m_LayoutLocation);
    flag |= EditInst<int>("m_Offset", inst.m_Offset);

    flag |= EditInst<GlslShader::Type>("m_Type", inst.m_Type);

    return flag;
}

template <>
bool Editor::Edit<GlslShader>(const std::string& label, GlslShader& inst)
{
    bool flag{ 0 };
    flag |= EditInstList<GlslShader::UniformVariable>("m_UniformBlocks", inst.m_UniformVariables);
    flag |= EditInstList<GlslShader::UniformBlock>("m_UniformBlocks", inst.m_UniformBlocks);

    return flag;
}
